# -*- coding: utf-8 -*-
from core import app
from auth import auth, login as auth_login, logout as auth_logout
from flask import redirect, url_for, render_template, g, request, jsonify
from models import User, Activity, ActivityInvite, RenrenUser, ActivityType
from sqlalchemy import and_
from forms import ActivityForm
from config import SITE_PATH
from util import get_activity_cover_path, get_tmp_activity_cover_path
from shutil import move
import os
from renren_api import *

@app.route('/')
@auth
def home():
    activities = Activity.query.filter(Activity.is_public == True).filter(Activity.state != u'取消')
    types = ActivityType.query.all()
    return render_template('home.html', activities=activities, types=types)

### login related views
@app.route('/login', methods=['GET', 'POST'])
def login():
    #for test use
    if request.method == 'GET':
        return render_template('login.html')
    else:
        user = User.query.filter(User.name == request.form['name']).first()
        auth_login(user)
        return redirect('/')
    #redirect to loginByRenren, this function should be enhanced later
#    return redirect(url_for('login_by_renren'))

@app.route('/loginbyrenren')
def login_by_renren():
    verification_code = request.args.get("code")
    args = dict(client_id=RENREN_APP_API_KEY, redirect_uri='http://localhost:5000/loginbyrenren')   
    error = request.args.get("error")
    if error:
        args["error"] = error
        args["error_description"] = request.args.get("error_description")
        args["error_uri"] = request.args.get("error_uri")

        args = dict(error=args)
        return args["error_description"]
    elif verification_code:
        args["client_secret"] = RENREN_APP_SECRET_KEY
        args["code"] = verification_code
        args["grant_type"] = "authorization_code"
        response = urllib.urlopen(RENREN_ACCESS_TOKEN_URI + "?" + urllib.urlencode(args)).read()
        access_token = parse_json(response)["access_token"]        
        '''Obtain session key from the Resource Service.'''
        session_key_request_args = {"oauth_token": access_token}
        response = urllib.urlopen(RENREN_SESSION_KEY_URI + "?" + urllib.urlencode(session_key_request_args)).read()
        session_key = str(parse_json(response)["renren_token"]["session_key"])
        
        '''Requesting the Renren API Server obtain the user's base info.'''
        params = {"method": "users.getInfo", "fields": "name,tinyurl"}
        api_client = RenRenAPIClient(session_key, RENREN_APP_API_KEY, RENREN_APP_SECRET_KEY)
        response = api_client.request(params);
        if type(response) is list:
            response = response[0]
        user_id = response["uid"]
        name = response["name"]
        avatar = response["tinyurl"]

        renren_user = RenrenUser.query.filter(RenrenUser.renren_id == user_id).first()
        if renren_user is None:
            renren_user = RenrenUser(name, avatar, user_id)
            renren_user.save()
        elif renren_user.portrait != avatar:
            renren_user.portrait = avatar
            renren_user.save()
        auth_login(renren_user)

        return redirect("/")
    else:
        args["response_type"] = "code"
        args["scope"] = "publish_feed email status_update"
        return redirect(
            RENREN_AUTHORIZATION_URI + "?" +
            urllib.urlencode(args))

@app.route('/logout')
@auth
def logout():
    auth_logout(g.user)
    return redirect(url_for('home'))
### login related views

### activity related views
@app.route('/activity/create', methods=['GET', 'POST'])
@auth
def create():
    form = ActivityForm(request.form)
    tmp_path = SITE_PATH + get_tmp_activity_cover_path(g.user.id)
    if os.path.isfile(tmp_path):
        os.remove(tmp_path)         
    if request.method == 'POST' and form.validate():
        invite_user_list = request.form['invite-list'].split('&') 
        invite_users = User.query.filter(User.id.in_(invite_user_list))           
        activity = form.create_activity(g.user, invite_users)
        #save the cover image if there is one        
        cover_path = get_activity_cover_path(activity.id)
        full_cover_path = SITE_PATH + cover_path
        if os.path.isfile(tmp_path):
            move(tmp_path, full_cover_path)
            activity.image = cover_path
            activity.save()
        return redirect('/activity/detail/' + str(activity.id))
    return render_template('activity/create.html', form=form, image='/static/activity/default.png')

@app.route('/activity/list')
def activity_list():#the name should not be list, or there may be a conflict to the buildin name, Important!!!
    activities = Activity.query.filter(Activity.is_public == True).filter(Activity.state != u'取消')
    type = request.args.get('type')
    if type and type != 'all':
        activities = activities.filter(Activity.activity_type_id == type)
    key = request.args.get('key')    
    if key:
        key = '%' + key + '%'
        activities = activities.filter(Activity.title.like(key))
    return render_template('activity/list.html', activities=activities)

@app.route('/activity/detail/<int:activity_id>')
def detail(activity_id):
    activity = Activity.get(activity_id)
    if activity is None:
        return render_template('error.html', error=u'该活动不存在')
    invite = activity.invites.filter(ActivityInvite.participant == g.user).first()
    if invite:
        user_state = invite.response
    else:
        user_state = u'未参加'
    privilege = {'edit': False, 'cancel':False, 'invite':False, 'rsvp': False}
    if g.user:
        privilege['rsvp'] = True
        if activity.creator == g.user:
            privilege['edit'] = True
            privilege['cancel'] = True
            privilege['invite'] = True
        if activity.allow_invitee_invite:
            privilege['invite'] = True 
    
    return render_template('activity/detail.html', activity=activity, privilege=privilege, user_state=user_state)

@app.route('/activity/edit/<int:activity_id>', methods=['GET', 'POST'])
@auth
def edit(activity_id):
    activity = Activity.get(activity_id)
    #check if the user is the creator
    if activity.creator == g.user:        
        form = ActivityForm(request.form, activity)
        if request.method == 'POST' and form.validate():
            form.populate_obj(activity)
            activity.save()
            return redirect('/activity/detail/' + str(activity.id))
        return render_template('activity/edit.html', form=form, activity=activity)
    else:
        return render_template('error.html', error=u'你没有权限编辑这个活动')

@app.route('/activity/cancel/<int:activity_id>', methods=['GET', 'POST'])
@auth
def cancel(activity_id):
    activity = Activity.get(activity_id)
    if activity.creator == g.user:
        if request.method == 'POST':
            #here is for test ,for real use, send message to the other participants
            message = request.form['message']
            activity.state = u'取消'
            activity.save()
            return message
            
        return render_template('activity/cancel.html', activity=activity)
    else:
        return render_template('error.html', error=u'你没有权限编辑这个活动')
    
@app.route('/activity/invite/<int:activity_id>', methods=['GET', 'POST'])
@auth
def invite(activity_id):       
    activity = Activity.get(activity_id)
    if request.method == 'GET':
        return render_template('activity/invite.html', activity=activity)
    if activity.creator == g.user or activity.allow_invitee_invite:
        invite_user_list = request.form['invite-list'].split('&') 
        invite_users = User.query.filter(User.id.in_(invite_user_list))
        activity.add_invitees(invite_users, u'未处理')
        activity.save()
        return redirect('/activity/detail/' + str(activity.id))
    else:
        return render_template('error.html', error=u'你没有权限编辑这个活动')
    
@app.route('/activity/rsvp/<int:activity_id>', methods=['POST'])
@auth
def rsvp(activity_id):
    if 'attend' in request.form:
        response = u'参加'
    elif 'maybe' in request.form:
        response = u'可能参加'
    elif 'decline' in request.form:
        response = u'不参加'
    activity = Activity.get(activity_id)
    invite = activity.invites.filter(ActivityInvite.participant == g.user).first()
    if invite is None:
        if activity.need_approve:
            response = u'待审核'
        activity.add_invitee(g.user, response)        
    else:
        invite.response = response
    activity.save()
    return response

@app.route('/activity/uploadPhoto', methods=['POST'])
@auth
def upload_photo():
    file = request.files['photo']
    activity_id = request.form.get('id', None)
    if file:
        if activity_id:
            path = get_activity_cover_path(activity_id)
            activity = Activity.get(activity_id)
            if activity.image != path:
                activity.image = path;
                activity.save()
        else:
            path = get_tmp_activity_cover_path(g.user.id)
        file.save(SITE_PATH + path)
    return path + '?' + (os.urandom(6)).encode('hex')

@app.route('/activity/candidates/<int:activity_id>')
@auth
def candidates(activity_id):
    if activity_id == 0:
        users = User.query.filter(User.id != g.user.id)
    else:
        users = User.query.filter(~User.activity_invites.any(ActivityInvite.activity_id == activity_id)).all()
    res = dict(candidates=[])
    for user in users:
        user_dict = {'id': user.id, 'name': user.name, 'portrait': user.portrait}
        res['candidates'].append(user_dict)
    return jsonify(res)
@app.route('/invites')
@auth
def get_activities_invited():
    activities = Activity.query.filter(Activity.invites.any(and_(ActivityInvite.participant == g.user, ActivityInvite.response == u'未处理')))
    return render_template('invites.html', activities=activities)

@app.route('/inviteCount')
@auth
def invite_count():
    return str(ActivityInvite.query.filter(ActivityInvite.participant == g.user).filter(ActivityInvite.response == u'未处理').count())
### activity related views